﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Threading;
using System.Web;

namespace WayProbe
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                switch (Properties.Settings.Default.SendMode.ToUpper())
                {
                    case "EMAIL": //以发送邮件的方式提交本地信息
                        {
                            var email = new SmtpClient(Properties.Settings.Default.EmailSendHost, Properties.Settings.Default.EmailSendPort);
                            email.Timeout = Properties.Settings.Default.EmailTimeout;
                            email.Credentials = new NetworkCredential(Properties.Settings.Default.EmailSendUsername, Properties.Settings.Default.EmailSendPassword);
                            email.DeliveryMethod = SmtpDeliveryMethod.Network;
                            MailMessage msg = new MailMessage();
                            msg.BodyEncoding = Encoding.UTF8;
                            msg.Body = "This is a WayProbe message, check mail property for more information. Do not reply.";
                            msg.IsBodyHtml = true;
                            msg.To.Add(Properties.Settings.Default.EmailSendTo);
                            msg.Subject = "Way Probe Info";
                            msg.From = new MailAddress(Properties.Settings.Default.EmailSendFrom, Properties.Settings.Default.HeartbeatID, Encoding.UTF8);
                            email.Send(msg);
                            WriteLog("Email sent.");
                        }
                        break;
                    case "STETHOCOPE": //以访问目标的方式提交信息
                        {
                            HttpWebRequest request = (HttpWebRequest)WebRequest.Create($"{Properties.Settings.Default.StethocopeServer}/pulsehandler.ashx?sender={Properties.Settings.Default.HeartbeatID}");
                            RequestState state = new RequestState();
                            state.request = request;
                            var result = request.BeginGetResponse(StethocopeBack, state);
                            ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), request, Properties.Settings.Default.StethocopeTimeout, true);
                            allDone.WaitOne();
                            state.response.Close();
                        }
                        break;
                    default:
                        if (Properties.Settings.Default.Interact)
                        {
                            WriteLog("Unsupported sending mode!");
                            Console.WriteLine("Sending mode is not supported. Press any key to quit.");
                            Console.ReadKey();
                        }
                        return;
                }
                if (Properties.Settings.Default.Interact)
                {
                    Console.WriteLine("Information sent. Press any key to quit.");
                    Console.ReadKey();
                }
            }
            catch (Exception ex)
            {
                if (Properties.Settings.Default.Interact)
                {
                    Console.WriteLine($"Error: {ex.Message}");
                    Console.ReadKey();
                }
                WriteLog($"Error: {ex.Message}\r\n{ex.StackTrace}");
            }
        }

        static ManualResetEvent allDone = new ManualResetEvent(false);

        static void StethocopeBack(IAsyncResult ar)
        {
            var response = (ar.AsyncState as HttpWebRequest).EndGetResponse(ar);
            //todo: read response
            allDone.Set();
        }

        static void TimeoutCallback(object state, bool timedOut)
        {
            if (timedOut)
            {
                HttpWebRequest request = state as HttpWebRequest;
                if (request != null)
                {
                    request.Abort();
                }
            }
        }

        static void WriteLog(string message)
        {
            var logpath = $"{Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)}/wayprobe";
            if (!Directory.Exists(logpath))
            {
                Directory.CreateDirectory(logpath);
            }
            var filepath = $"{logpath}/{DateTime.Now.ToString("yyyy_MM")}.log";
            StreamWriter sw;
            sw = new StreamWriter(filepath, true, Encoding.UTF8);
            sw.WriteLine($"{DateTime.Now.ToString("dd HH:mm:ss")} {message}");
            sw.Close();
        }
    }
}
